package cc.eddic.practice.concurrency.impl;

import cc.eddic.practice.concurrency.LogItem;
import cc.eddic.practice.concurrency.LogItemParser;
import cc.eddic.practice.concurrency.LogParser;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
@Qualifier("LogParserWithRecursiveImpl")
public class LogParserWithRecursiveImpl implements LogParser {

    @Override
    public Map<String, List<LogItem>> parse(String folderName) {
        Map<String, List<LogItem>> result = new HashMap<>();
        walk(folderName).stream().filter(x -> x.getName().endsWith(".log")).forEach(file -> {
            try (val lines = Files.lines(file.toPath())) {
                val items = lines.map(logItemParser::parse).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
                result.put(file.getAbsolutePath(), items);
            } catch (IOException ex) {
                log.error(ex.getMessage(), ex);
            }
        });
        return result;
    }

    private List<File> walk(String folder) {
        List<File> files = new ArrayList<>();
        walk(new File(folder), files);
        return files;
    }

    private void walk(File file, List<File> result) {
        val files = file.listFiles();
        if (null == files) {
            return;
        }
        for (val f : files) {
            if (f.isDirectory()) {
                walk(f, result);
            } else {
                result.add(f);
            }
        }
    }

    public LogParserWithRecursiveImpl(LogItemParser logItemParser) {
        this.logItemParser = logItemParser;
    }

    private final LogItemParser logItemParser;
}
